package org.lds.message.center.admin.business.template.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lds.message.center.admin.business.app.entity.App;
import org.lds.message.center.admin.business.app.mapper.AppMapper;
import org.lds.message.center.admin.business.template.converter.*;
import org.lds.message.center.admin.business.template.entity.Template;
import org.lds.message.center.admin.business.template.mapper.TemplateMapper;
import org.lds.message.center.admin.business.template.model.request.*;
import org.lds.message.center.admin.business.template.model.response.*;
import org.lds.message.center.admin.business.template.service.TemplateBaseService;
import org.lds.message.center.admin.kafka.KafkaProducer;
import org.lds.message.center.common.model.ResultDTO;
import org.lds.message.center.common.model.db.OrderBy;
import org.lds.message.center.common.model.db.PageResult;
import org.lds.message.center.common.model.request.GetTemplateAdminRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 基础服务实现类
 *
 * @author lidongsheng
 * @since 2024-12-22
 */
@Slf4j
@Service
public class TemplateBaseServiceImpl implements TemplateBaseService {

    @Autowired
    private TemplateMapper templateMapper;

    @Autowired
    private AppMapper appMapper;

    @Autowired
    private TemplateBaseCreateRequestToEntityConverter templateBaseCreateRequestToEntityConverter;

    @Autowired
    private TemplateBaseUpdateRequestToEntityConverter templateBaseUpdateRequestToEntityConverter;

    @Autowired
    private TemplateBaseListRequestToEntityConverter templateBaseListRequestToEntityConverter;

    @Autowired
    private TemplateToBaseResponseConverter templateToBaseResponseConverter;

    @Autowired
    private TemplateBaseListPageRequestToEntityConverter templateBaseListPageRequestToEntityConverter;

    @Autowired
    private TemplateBaseGetByKeyRequestToEntityConverter templateBaseGetByKeyRequestToEntityConverter;

    @Autowired
    private KafkaProducer kafkaProducer;

    @Value("${message-center.clear-template-cache.topic}")
    private String clearTemplateCacheTopic;

    @Override
    @Transactional
    public ResultDTO<TemplateBaseResponse> createTemplate(TemplateBaseCreateRequest request) {
        try {
            Template template = templateBaseCreateRequestToEntityConverter.convert(request);
            templateMapper.insert(template);
            TemplateBaseResponse response = templateToBaseResponseConverter.convert(template);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<TemplateBaseBatchCreateResponse> batchCreateTemplate(TemplateBaseBatchCreateRequest request) {
        TemplateBaseBatchCreateResponse response = TemplateBaseBatchCreateResponse.builder()
                .responses(request.getRequests().stream().map(this::createTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<TemplateBaseDeleteResponse> deleteTemplate(TemplateBaseDeleteRequest request) {
        Template template = templateMapper.selectById(request.getId());
        if (template != null) {
            templateMapper.deleteById(request.getId());
            App app = appMapper.selectById(template.getAppId());
            if (app != null) {
                // kafka发送消息
                kafkaProducer.send(clearTemplateCacheTopic, app.getName(), new GetTemplateAdminRequest(app.getName(), template.getName()));
            }
        }

        TemplateBaseDeleteResponse response = TemplateBaseDeleteResponse.builder()
                .request(request)
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<TemplateBaseBatchDeleteResponse> batchDeleteTemplate(TemplateBaseBatchDeleteRequest request) {
        TemplateBaseBatchDeleteResponse response = TemplateBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().stream().map(this::deleteTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Transactional
    @Override
    public ResultDTO<TemplateBaseResponse> updateTemplate(TemplateBaseUpdateRequest request) {
        try {
            Template template = templateBaseUpdateRequestToEntityConverter.convert(request);

            Template currTemplate = templateMapper.selectById(request.getId());
            if (currTemplate != null) {
                templateMapper.updateById(template);

                if (!StringUtils.equals(currTemplate.getSubject(), request.getSubject()) ||
                        !StringUtils.equals(currTemplate.getText(), request.getText()) ||
                        currTemplate.getEnable() != request.getEnable()) {
                    App app = appMapper.selectById(currTemplate.getAppId());
                    if (app != null) {
                        kafkaProducer.send(clearTemplateCacheTopic, app.getName(), new GetTemplateAdminRequest(app.getName(), template.getName()));
                    }
                }
            }



            TemplateBaseResponse response = templateToBaseResponseConverter.convert(template);
            return ResultDTO.success(response);
        } catch (DuplicateKeyException e) {
            return ResultDTO.fail("DATA_REPEAT", "数据重复");
        }
    }

    @Transactional
    @Override
    public ResultDTO<TemplateBaseBatchUpdateResponse> batchUpdateTemplate(TemplateBaseBatchUpdateRequest request) {
        TemplateBaseBatchUpdateResponse response = TemplateBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().stream().map(this::updateTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseResponse> getTemplateById(TemplateBaseGetByIdRequest request) {
        Template template = templateMapper.selectById(request.getId());
        if (template == null) {
            return ResultDTO.success();
        }

        TemplateBaseResponse response = templateToBaseResponseConverter.convert(template);
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseListResponse> getTemplateByIds(TemplateBaseGetByIdsRequest request) {
        List<Template> list = request.getIds().stream().map(id -> templateMapper.selectById(id)).collect(Collectors.toList());
        return ResultDTO.success(TemplateBaseListResponse.builder()
                .templates(list.stream().map(template -> templateToBaseResponseConverter.convert(template)).collect(Collectors.toList()))
                .build());
    }

    @Override
    public Template getTemplateByKey(TemplateBaseGetByKeyRequest request) {
        if (request == null) return null;
        if (!request.isHasBusinessKey()) return null;
        return templateMapper.selectOne(new QueryWrapper<>(templateBaseGetByKeyRequestToEntityConverter.convert(request)));
    }

    @Override
    public ResultDTO<TemplateBaseListResponse> listTemplate(TemplateBaseListRequest request) {
        QueryWrapper<Template> wrapper = new QueryWrapper<>(templateBaseListRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            wrapper.orderByDesc(request.getOrderByKey());
        }

        List<Template> templates = templateMapper.selectList(wrapper);

        TemplateBaseListResponse response = TemplateBaseListResponse.builder()
                .templates(templates.stream().map(templateToBaseResponseConverter::convert).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseListResponse> listAllTemplate(OrderBy orderBy) {
        TemplateBaseListRequest templateRequest = TemplateBaseListRequest.builder().build();
        templateRequest.setOrderByKey(orderBy.getOrderByKey());
        return listTemplate(templateRequest);
    }

    @Override
    public ResultDTO<PageResult<TemplateBaseResponse>> listTemplatePage(TemplateBaseListPageRequest request) {
        Page<Template> page = new Page<>(request.getPageNum(), request.getPageSize(), true);

        QueryWrapper<Template> wrapper = new QueryWrapper<>(templateBaseListPageRequestToEntityConverter.convert(request));
        if (StringUtils.isNotEmpty(request.getOrderByKey())) {
            if (request.getOrderByDesc() != null && request.getOrderByDesc().booleanValue() == false) {
                wrapper.orderByAsc(request.getOrderByKey());
            } else {
                wrapper.orderByDesc(request.getOrderByKey());
            }
        }

        IPage<Template> pageResult = templateMapper.selectPage(page, wrapper);

        PageResult<TemplateBaseResponse> response = new PageResult(
                pageResult.getTotal(), pageResult.getPages(), pageResult.getCurrent(), pageResult.getSize(),
                pageResult.getRecords().stream().map(templateToBaseResponseConverter::convert).collect(Collectors.toList()));
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseBatchCreateResponse> batchCreateTemplateAsync(TemplateBaseBatchCreateRequest request) {
        TemplateBaseBatchCreateResponse response = TemplateBaseBatchCreateResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::createTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseBatchDeleteResponse> batchDeleteTemplateAsync(TemplateBaseBatchDeleteRequest request) {
        TemplateBaseBatchDeleteResponse response = TemplateBaseBatchDeleteResponse.builder()
                .responses(request.getRequests().parallelStream().map(this::deleteTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

    @Override
    public ResultDTO<TemplateBaseBatchUpdateResponse> batchUpdateTemplateAsync(TemplateBaseBatchUpdateRequest request) {
        TemplateBaseBatchUpdateResponse response = TemplateBaseBatchUpdateResponse.builder()
                .requests(request.getRequests().parallelStream().map(this::updateTemplate).collect(Collectors.toList()))
                .build();
        return ResultDTO.success(response);
    }

}
